"""
@Author: li
@Email: lijianqiao2906@live.com
@FileName: auth.py
@DateTime: 2025/07/06
@Docs: 认证服务
"""

from app.core.exceptions import BadRequestException
from app.schemas import LoginRequest, LoginResponse, TokenResponse, UserRead
from app.services.user import UserService
from app.utils.security import create_access_token, verify_password


class AuthService:
    """认证服务"""

    def __init__(self):
        self.user_service = UserService()

    async def login(self, login_data: LoginRequest) -> LoginResponse:
        """用户登录认证

        Args:
            login_data: 登录请求数据

        Returns:
            包含令牌和用户信息的登录响应

        Raises:
            BadRequestException: 用户不存在或密码错误
        """
        # 1. 根据用户名或邮箱查找用户
        user_check = await self.user_service.get_user_by_username_or_email(login_data.username)
        if not user_check:
            raise BadRequestException("用户不存在或密码错误")

        # 2. 验证密码
        if not verify_password(login_data.password, user_check.password_hash):
            raise BadRequestException("用户不存在或密码错误")

        # 3. 检查用户是否被禁用
        if not user_check.is_active:
            raise BadRequestException("用户已被禁用，请联系管理员")

        # 4. 获取带有角色的完整用户信息
        user = await self.user_service.get_user_with_roles(user_check.id)
        if not user:
            # 这种情况理论上不应该发生，因为上面已经检查过用户存在
            raise BadRequestException("无法获取用户信息")

        # 5. 创建访问令牌
        access_token, expire_timestamp = create_access_token(user.id)

        # 6. 更新用户最后登录时间 (可以后台任务执行)
        # 注意：这个操作移到API层使用后台任务处理，以避免阻塞登录流程
        # await self.user_service.update_last_login(user.id)

        # 7. 组装响应数据
        token_response = TokenResponse(
            access_token=access_token,
            expires_in=expire_timestamp,
            token_type="bearer",
        )
        # 此处 User 对象已经预加载了 roles，可以直接验证
        user_info = UserRead.model_validate(user, from_attributes=True)

        return LoginResponse(token=token_response, user=user_info)


auth_service = AuthService()
